{------------------------------Main Form----------------------------------
-------------------- Torque Game Engine - GUI Masser ---------------------
---------------------- Roll Game Team 2014 - BLumia ----------------------
   Hello and this is a WYSIWYG TGE GUI Editor which is designed for Marble
Blast(okay..for our mod Happy Roll). Since the MB's original GUI Editor is
really bad so I plan to make an Easy-to-Use one.
   This project is created by BLumia(Gary),and it's open source.That means
you can download and edit this program freely.
   This program is under MIT licence so if you are going to edit this pro-
gram please credit us. Thank you very much
--------------------------------------------------------------------------
 Progress:                    [V] Done  [P] in progess [ ] not started
    1. Write a class for GUICtrls                                  [V]
    2. A correct way to read a TGE GUI file                        [V]
    3. Show all GUICtrls at the TreeView Ctrl and StringGrid Ctrl  [V]
    4. Draw the GUI on Panel Ctrl                                  [V]
    5. Save as a GUI file                                          [P]
    6. Can edit a gui by edit the numbers in StringGrid Ctrl       [P]
    7. Can edit a gui by drag Ctrls on PaintBox                    [P]
    8. To be added....                                             [ ]
-------------------------------------------------------------------------}

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  StdCtrls, Buttons, Grids, ComCtrls, guictrlclass, BLumiahint, TreeXML;

type

    TAGuiCtrls = array of TGuiCtrl;

  { TForm1 }

  TForm1 = class(TForm)
    ApplyChange: TButton;
    AskBalloon: TImage;
    AskBalloonText: TLabel;
    balloonLeft: TImage;
    balloonMidd: TImage;
    balloonRight: TImage;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    CheckBox1: TCheckBox;
    Image5: TImage;
    NextText: TButton;
    DrawGUIBtn: TButton;
    GroupBox1: TGroupBox;
    CtrlCover: TImage;
    Guider: TImage;
    GuideText: TLabel;
    HelpBtn: TButton;
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    MPos: TLabel;
    NewGUICtrlBtn: TButton;
    Panel1: TPanel;
    Panel2: TPanel;
    ResolutionCombo: TComboBox;
    ScrollBox1: TScrollBox;
    ComboBox1: TComboBox;
    ComboBox2: TComboBox;
    OpenDialog1: TOpenDialog;
    SaveBtn: TBitBtn;
    Label1: TLabel;
    LoadFileBtn: TButton;
    StaticText1: TStaticText;
    StringGrid1: TStringGrid;
    TreeView1: TTreeView;
    VisibleDrawGuiBtn: TButton;
    procedure ApplyChangeClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure CtrlCoverMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure CtrlCoverMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure CtrlCoverMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormResize(Sender: TObject);
    procedure NextTextClick(Sender: TObject);
    procedure VisibleDrawGuiBtnClick(Sender: TObject);
    procedure DrawGUIBtnClick(Sender: TObject);
    procedure ComboBox1Exit(Sender: TObject);
    procedure ComboBox2Exit(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure HelpBtnClick(Sender: TObject);
    procedure LoadFileBtnClick(Sender: TObject);
    procedure NewGUICtrlBtnClick(Sender: TObject);
    procedure DrawGUI(aItem:TTreeNode);
    procedure VisibleDrawGUI(aItem:TTreeNode);
    procedure ClearGUI;
    procedure realUpdate;
    procedure SaveBtnClick(Sender: TObject);
    procedure StringGrid1SelectCell(Sender: TObject; aCol, aRow: Integer;
      var CanSelect: Boolean);
    procedure TreeView1Click(Sender: TObject);
    procedure outputAsGuiFile(s:string;aItem:TTreeNode);
    procedure setAskBalloonText(TextLO,TextLT:string);
    procedure setBalloonText(textNum:integer;TextLO,TextLT:string);
    function getIdFormNodeName(ts: string):Integer;
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  parentNodeNow,nodeNow: TTreeNode;
  guiCtrls: array of TGuiCtrl;
  ctrlPic:array of TImage;
  ttext: Text; //for GUI saving
  mouseX,mouseY,selectId,dlgcase:integer;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.LoadFileBtnClick(Sender: TObject);
var
  guiFile: Text;
  ts,filepath: string;
  fuck:TGuiCtrl;
  //--var for guiCtrls
  idNow,codeLine:integer;
begin
  ClearGUI;
  StaticText1.Visible:=false;
  Label1.Caption:='No file loaded..';
  Treeview1.Items.Clear;
  nodeNow:=Treeview1.Items.AddFirst(nil, '0:GUI TreeView');
begin
  with OpenDialog1 do
  begin
    Filter:='TGE GUI File(*.gui)|*.gui';
    DefaultExt:='gui';
    FileName:='';
    Options:=[ofHideReadOnly,ofEnableSizing];
    if Execute then
      if ofExtensionDifferent in Options then
        Options:=[ofHideReadOnly,ofEnableSizing]
      else
        begin
        filepath:=utf8toansi(FileName);
        end;
  end;
end;
  Label1.Caption:=ansitoutf8(filepath);
  if not FileExists(PChar(filepath)) then exit;
  //---init tree counter
  idNow:=0;   codeLine:=0;
  //--------------------
  assignfile(guiFile, filepath);//'test.gui'
  reset(guiFile);
  while not EOF(guiFile) do
  begin
    readln(guiFile, ts);
    codeLine:=codeLine+1;//line counter
    while (copy(ts, 1, 1) = #9 ) do Delete(ts, 1, 1);// delete TAB first
    while (copy(ts, 1, 1) = #32) do Delete(ts, 1, 1);// then del SPACE
    //--------go to next line
    if (copy(ts, 1, 2) = '//') then continue;
    //-------- new GuiCtrl Init
    if (copy(ts, 1, 3) = 'new') then
    begin
       Delete(ts, 1, 4);
       SetLength(guiCtrls, TreeView1.Items.Count+1);         //gctrl[n](n+1个，第一项废掉
       guiCtrls[TreeView1.Items.Count]:=TGuiCtrl.create;
       idNow:=TreeView1.Items.Count;                         //idNow:=n
       guiCtrls[idNow].codeLine:=codeLine;                   //line counter
       guiCtrls[idNow].setFunctionName(copy(ts,1,pos('(',ts)-1));
       Delete(ts,1,pos('(',ts));
       guiCtrls[idNow].setName(copy(ts,1,pos(')',ts)-1));

       parentNodeNow:=nodeNow;
       nodeNow:=Treeview1.Items.AddChild(nodeNow,inttostr(TreeView1.Items.Count)+
       ':'+guiCtrls[idNow].functionName);

       guiCtrls[idNow].parent:=getIdFormNodeName(nodeNow.Parent.Text);
    end;
    //-------- GuiCtrl-Profile
    if (copy(ts, 1, 7) = 'profile') then
    begin
       Delete(ts, 1, 11);
       guiCtrls[idNow].setProfile(copy(ts,1,pos('"',ts)-1));
    end;
    //-------- GuiCtrl-horizSizing
    if (copy(ts, 1, 11) = 'horizSizing') then
    begin
       Delete(ts, 1, 15);
       guiCtrls[idNow].setHorizSizing(copy(ts,1,pos('"',ts)-1));
    end;
    //-------- GuiCtrl-vertSizing
    if (copy(ts, 1, 10) = 'vertSizing') then
    begin
       Delete(ts, 1, 14);
       guiCtrls[idNow].setVertSizing(copy(ts,1,pos('"',ts)-1));
    end;
    //-------- GuiCtrl-Position
    if (copy(ts, 1, 8) = 'position') then
    begin
       Delete(ts, 1, 12);
       guiCtrls[idNow].setPosition(copy(ts,1,pos('"',ts)-1));
       // RealPos fix moved to realUpdate function
    end;
    //-------- GuiCtrl-Extent
    if (copy(ts, 1, 6) = 'extent') then
    begin
       Delete(ts, 1, 10);
       guiCtrls[idNow].setExtent(copy(ts,1,pos('"',ts)-1));
       // RealExt fix moved to realUpdate function
    end;
    //-------- GuiCtrl-minExtent
    if (copy(ts, 1, 9) = 'minExtent') then
    begin
       Delete(ts, 1, 13);
       guiCtrls[idNow].setMinExtent(copy(ts,1,pos('"',ts)-1));
    end;
    //-------- GuiCtrl-Visible
    if (copy(ts, 1, 7) = 'visible') then
    begin
       Delete(ts, 1, 11);
       guiCtrls[idNow].setVisible(copy(ts,1,pos('"',ts)-1));
       //do the same thing to visible... -- Chirsno
       if(guiCtrls[idNow].parent=0)then guiCtrls[idNow].visoverride:=guiCtrls[idNow].visible
       else
       guiCtrls[idNow].visoverride:=guiCtrls[guiCtrls[idNow].parent].visoverride and
       guiCtrls[idNow].visible;
    end;
    //-------- GuiCtrl-Command
    if (copy(ts, 1, 7) = 'command') then
    begin
       Delete(ts, 1, 11);
       guiCtrls[idNow].setCommand(copy(ts,1,pos('"',ts)-1));
    end;
    //-------- GuiCtrl-Bitmap
    if (copy(ts, 1, 6) = 'bitmap') then
    begin
       Delete(ts, 1, 10);
       guiCtrls[idNow].setBitmap(copy(ts,1,pos('"',ts)-1));
    end;
    //-------- GuiCtrl-End a Node
    if (copy(ts, 1, 2) = '};') then
    begin
       //showmessage('codeLine:'+inttostr(codeLine)+' '+nodeNow.Text);
       //if (nodeNow.parent<>nil)then begin
       nodeNow:=nodeNow.Parent; //Why!Why?Why...
       parentNodeNow:=nodeNow.Parent;
       //end;
    end;
  end;
  realUpdate;//rpos and rext
  showmessage('it is done');
  closefile(guiFile);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  filepath,ts:string;
  idNow,codeLine:integer;
  guiFile: Text;
begin
  nodeNow:=Treeview1.Items.AddFirst(nil, '0:GUI TreeView');
  ResolutionCombo.ItemIndex:=0;

  SetLength(guiCtrls, 1);
  guiCtrls[0]:=TGuiCtrl.create;
  guiCtrls[0].setName('yooooooooo');
  guiCtrls[0].setParent(-1);
  guiCtrls[0].setPosition('0 0');
  guiCtrls[0].setExtent('800 600');
  guiCtrls[0].rext.horiz:=800;
  guiCtrls[0].rext.vert:=600;
  ComboBox1.Visible := False;
  ComboBox2.Visible := False;
  CtrlCover.Left:=-96;
  CtrlCover.Top:=528;
  selectId:=0;

  //参数检测
  if paramcount>0 then begin
  //showmessage(pchar(ansitoutf8(paramstr(1))));
     if FileExists(pchar(paramstr(1))) then begin
        if ExtractFileExt(paramstr(1))='.gui' then begin
          filepath := utf8toansi(ansitoutf8(paramstr(1)));
          //showmessage(filename);诶。。我说Lazarus啊。。这看上去一坨屎的ansi字符串您照样用诶。。
          Label1.Caption := ansitoutf8(filepath);

           if not FileExists(PChar(filepath)) then exit;
           //---init tree counter
           idNow:=0;   codeLine:=0;
           //--------------------
           assignfile(guiFile, filepath);//'test.gui'
           reset(guiFile);
           while not EOF(guiFile) do
           begin
             readln(guiFile, ts);
             codeLine:=codeLine+1;//line counter
             while (copy(ts, 1, 1) = #9 ) do Delete(ts, 1, 1);// delete TAB first
             while (copy(ts, 1, 1) = #32) do Delete(ts, 1, 1);// then del SPACE
             //--------go to next line
             if (copy(ts, 1, 2) = '//') then continue;
             //-------- new GuiCtrl Init
             if (copy(ts, 1, 3) = 'new') then
             begin
                Delete(ts, 1, 4);
                SetLength(guiCtrls, TreeView1.Items.Count+1);         //gctrl[n](n+1个，第一项废掉
                guiCtrls[TreeView1.Items.Count]:=TGuiCtrl.create;
                idNow:=TreeView1.Items.Count;                         //idNow:=n
                guiCtrls[idNow].codeLine:=codeLine;                   //line counter
                guiCtrls[idNow].setFunctionName(copy(ts,1,pos('(',ts)-1));
                Delete(ts,1,pos('(',ts));
                guiCtrls[idNow].setName(copy(ts,1,pos(')',ts)-1));

                parentNodeNow:=nodeNow;
                nodeNow:=Treeview1.Items.AddChild(nodeNow,inttostr(TreeView1.Items.Count)+
                ':'+guiCtrls[idNow].functionName);

                guiCtrls[idNow].parent:=getIdFormNodeName(nodeNow.Parent.Text);
             end;
             //-------- GuiCtrl-Profile
             if (copy(ts, 1, 7) = 'profile') then
             begin
                Delete(ts, 1, 11);
                guiCtrls[idNow].setProfile(copy(ts,1,pos('"',ts)-1));
             end;
             //-------- GuiCtrl-horizSizing
             if (copy(ts, 1, 11) = 'horizSizing') then
             begin
                Delete(ts, 1, 15);
                guiCtrls[idNow].setHorizSizing(copy(ts,1,pos('"',ts)-1));
             end;
             //-------- GuiCtrl-vertSizing
             if (copy(ts, 1, 10) = 'vertSizing') then
             begin
                Delete(ts, 1, 14);
                guiCtrls[idNow].setVertSizing(copy(ts,1,pos('"',ts)-1));
             end;
             //-------- GuiCtrl-Position
             if (copy(ts, 1, 8) = 'position') then
             begin
                Delete(ts, 1, 12);
                guiCtrls[idNow].setPosition(copy(ts,1,pos('"',ts)-1));
                //check its parent and compute real pos... -- Chirsno
                if(guiCtrls[idNow].parent=0)then guiCtrls[idNow].rpos:=guiCtrls[idNow].position
                else begin
                  guiCtrls[idNow].rpos.horiz:=guiCtrls[guiCtrls[idNow].parent].rpos.horiz+
                  guiCtrls[idNow].position.horiz;
                  guiCtrls[idNow].rpos.vert:=guiCtrls[guiCtrls[idNow].parent].rpos.vert+
                  guiCtrls[idNow].position.vert;
                end;
             end;
             //-------- GuiCtrl-Extent
             if (copy(ts, 1, 6) = 'extent') then
             begin
                Delete(ts, 1, 10);
                guiCtrls[idNow].setExtent(copy(ts,1,pos('"',ts)-1));
             end;
             //-------- GuiCtrl-minExtent
             if (copy(ts, 1, 9) = 'minExtent') then
             begin
                Delete(ts, 1, 13);
                guiCtrls[idNow].setMinExtent(copy(ts,1,pos('"',ts)-1));
             end;
             //-------- GuiCtrl-Visible
             if (copy(ts, 1, 7) = 'visible') then
             begin
                Delete(ts, 1, 11);
                guiCtrls[idNow].setVisible(copy(ts,1,pos('"',ts)-1));
                //do the same thing to visible... -- Chirsno
                if(guiCtrls[idNow].parent=0)then guiCtrls[idNow].visoverride:=guiCtrls[idNow].visible
                else
                guiCtrls[idNow].visoverride:=guiCtrls[guiCtrls[idNow].parent].visoverride and
                guiCtrls[idNow].visible;
             end;
             //-------- GuiCtrl-Command
             if (copy(ts, 1, 7) = 'command') then
             begin
                Delete(ts, 1, 11);
                guiCtrls[idNow].setCommand(copy(ts,1,pos('"',ts)-1));
             end;
             //-------- GuiCtrl-Bitmap
             if (copy(ts, 1, 6) = 'bitmap') then
             begin
                Delete(ts, 1, 10);
                guiCtrls[idNow].setBitmap(copy(ts,1,pos('"',ts)-1));
             end;
             //-------- GuiCtrl-End a Node
             if (copy(ts, 1, 2) = '};') then
             begin
                //showmessage('codeLine:'+inttostr(codeLine)+' '+nodeNow.Text);
                //if (nodeNow.parent<>nil)then begin
                nodeNow:=nodeNow.Parent; //Why!Why?Why...
                parentNodeNow:=nodeNow.Parent;
                //end;
             end;
           end;
           showmessage('it is done');
           realUpdate;
           StaticText1.Visible:=false;
           DrawGUI(TreeView1.Items.GetFirstNode);
        end else begin
          showmessage('This file is NOT a TGE GUI file') ;
        end
     end else begin
        showmessage('File not found');
     end
  end else begin
     //showmessage('command paramstr not found');
  end;
end;

procedure TForm1.HelpBtnClick(Sender: TObject);
begin
  Panel2.Visible:=True;
  Panel2.Top:=0;
  Panel2.Left:=0;
  Panel2.Width:=944;
  Panel2.Height:=639;
  Image1.Top:=0;
  Image1.Left:=0;
  Image1.Width:=944;
  Image1.Height:=639;
  Guider.Top:=170;
  Guider.Left:=540;
  Guider.Width:=304;
  Guider.Height:=472;
  //Text
  setAskBalloonText('0','!');
  setBalloonText(0,'','');
  dlgcase:=0;
end;

procedure TForm1.ComboBox1Exit(Sender: TObject);
begin
  with Sender as TComboBox do
  begin
    hide;
    if itemindex >= 0 then
      with StringGrid1 do
        Cells[col, row] := Items[itemindex];
  end;
end;

procedure TForm1.ApplyChangeClick(Sender: TObject);
var
  id,i:integer;
begin
  if Treeview1.Selected = nil then Exit;
  id:=strtoint(stringgrid1.cells[1,3]);
  if id = 0 then Exit;
  guiCtrls[id].setHorizSizing(stringgrid1.cells[1,5]);
  guiCtrls[id].setVertSizing(stringgrid1.cells[1,6]);
  //guiCtrls[id].setPosition(stringgrid1.cells[1,7]);
  guiCtrls[id].setExtent(stringgrid1.cells[1,8]);
  guiCtrls[id].visible:=boolean(strtoint(stringgrid1.Cells[1,10]));
  guiCtrls[id].setBitmap(stringgrid1.cells[1,12]);

  if ((CtrlCover.Left<>guiCtrls[id].rpos.horiz)
  or (CtrlCover.Top<>guiCtrls[id].rpos.vert)) and
  ((CtrlCover.Left<>-96) and (CtrlCover.Top<>528)) then
  begin
     guiCtrls[id].setPosition( //code should be looooooooooooooooooooooonnnnnnng
     inttostr(guiCtrls[id].position.horiz+CtrlCover.Left-guiCtrls[id].rpos.horiz)
     +' '+inttostr(guiCtrls[id].position.vert+CtrlCover.Top-guiCtrls[id].rpos.vert))
  end else guiCtrls[id].setPosition(stringgrid1.cells[1,7]);

  //140921 We should only change visible state
  //       rpos and rext moved to realUpdate func.
  //(Visible) update this and it's children... -- Chirsno
  if(guiCtrls[id].parent=0)then
  begin
    //guiCtrls[id].rpos:=guiCtrls[id].position;
    guiCtrls[id].visoverride:=guiCtrls[id].visible;
  end
  else begin
    //guiCtrls[id].rpos.horiz:=guiCtrls[guiCtrls[id].parent].rpos.horiz+
    //guiCtrls[id].position.horiz;
    //guiCtrls[id].rpos.vert:=guiCtrls[guiCtrls[id].parent].rpos.vert+
    //guiCtrls[id].position.vert;
    guiCtrls[id].visoverride:=guiCtrls[guiCtrls[id].parent].visoverride and
    guiCtrls[id].visible;
  end;
  for i:=id+1 to TreeView1.Items.Count-1 do//warning: this might be slow -- Chirsno
    begin
      //we should break if the current one is no longer a child of this...
      //checking this require additional time or memory. -- Chirsno
      //guiCtrls[i].rpos.horiz:=guiCtrls[guiCtrls[i].parent].rpos.horiz+
      //guiCtrls[i].position.horiz;
      //guiCtrls[i].rpos.vert:=guiCtrls[guiCtrls[i].parent].rpos.vert+
      //guiCtrls[i].position.vert;
      guiCtrls[i].visoverride:=guiCtrls[guiCtrls[i].parent].visoverride and
      guiCtrls[i].visible;
    end;
  realUpdate;//so we add this line
  ClearGUI;
  DrawGUI(TreeView1.Items.GetFirstNode);
end;

procedure TForm1.realUpdate;
var
   idNow,tmpcenter:integer;
   ratio:real;
begin
   //test
   for idNow:=1 to TreeView1.Items.Count-1 do begin//warning: this might be slow -- Chirsno
       //check its parent and compute real pos... -- Chirsno
       //and.. we should also do Sizing job here.. -- BLumia

       //realPos
       if(guiCtrls[idNow].parent= -1)then guiCtrls[idNow].rpos:=guiCtrls[idNow].position
       else begin
          //Sizing suit.
          case guiCtrls[idNow].horizSizing of
            widthH: guiCtrls[idNow].rpos.horiz:=guiCtrls[guiCtrls[idNow].parent].rpos.horiz;
            rightH: guiCtrls[idNow].rpos.horiz:=guiCtrls[guiCtrls[idNow].parent].rpos.horiz +
                                                guiCtrls[idNow].position.horiz;
            leftH : guiCtrls[idNow].rpos.horiz:=guiCtrls[guiCtrls[idNow].parent].rext.horiz -
                                                guiCtrls[idNow].extent.horiz;
            relativeH:begin
                      ratio:=(guiCtrls[idNow].position.horiz) / (guiCtrls[guiCtrls[idNow].parent].extent.horiz);
                      guiCtrls[idNow].rpos.horiz:= guiCtrls[guiCtrls[idNow].parent].rpos.horiz +
                                                   trunc((guiCtrls[guiCtrls[idNow].parent].rext.horiz) * ratio);
                      end;
            centerH:begin
                    tmpCenter:=((guiCtrls[guiCtrls[idNow].parent].rpos.horiz * 2)+(guiCtrls[guiCtrls[idNow].parent].rext.horiz)) div 2;
                    guiCtrls[idNow].rpos.horiz:=tmpCenter-(guiCtrls[idNow].extent.horiz div 2);
                    end;
          else
            guiCtrls[idNow].rpos.horiz:=guiCtrls[guiCtrls[idNow].parent].rpos.horiz + guiCtrls[idNow].position.horiz;
          end;

          case guiCtrls[idNow].vertSizing of
            heightV: guiCtrls[idNow].rpos.vert:=guiCtrls[guiCtrls[idNow].parent].rpos.vert;
            bottomV: guiCtrls[idNow].rpos.vert:=guiCtrls[guiCtrls[idNow].parent].rpos.vert +
                              guiCtrls[idNow].position.vert;
            topV   : guiCtrls[idNow].rpos.vert:=guiCtrls[guiCtrls[idNow].parent].rext.vert -
                              guiCtrls[idNow].extent.vert;
            relativeV:begin
                      ratio:= (guiCtrls[idNow].position.vert) / (guiCtrls[guiCtrls[idNow].parent].extent.vert);
                      guiCtrls[idNow].rpos.vert:= guiCtrls[guiCtrls[idNow].parent].rpos.vert +
                                                  trunc((guiCtrls[guiCtrls[idNow].parent].rext.vert) * ratio);
                      end;
            centerV: begin
                     tmpCenter:=((guiCtrls[guiCtrls[idNow].parent].rpos.vert * 2)+(guiCtrls[guiCtrls[idNow].parent].rext.vert)) div 2;
		     guiCtrls[idNow].rpos.vert:=tmpCenter-(guiCtrls[idNow].extent.vert div 2);
                     end;
          else
            guiCtrls[idNow].rpos.vert:=guiCtrls[guiCtrls[idNow].parent].rpos.vert + guiCtrls[idNow].position.vert;
          end;
       end;

       //realExtent
       if(guiCtrls[idNow].parent= -1)then guiCtrls[idNow].rext:=guiCtrls[idNow].extent
       else begin
          //Sizing suit.
          case guiCtrls[idNow].horizSizing of
            widthH: guiCtrls[idNow].rext.horiz:=guiCtrls[guiCtrls[idNow].parent].rext.horiz;
            rightH: guiCtrls[idNow].rext.horiz:=guiCtrls[idNow].extent.horiz ;
            relativeH:begin
                      ratio:=(guiCtrls[guiCtrls[idNow].parent].extent.horiz) / (guiCtrls[guiCtrls[idNow].parent].rext.horiz);
                      guiCtrls[idNow].rext.horiz:= trunc(guiCtrls[idNow].extent.horiz / ratio);
                      end;
            centerH:guiCtrls[idNow].rext.horiz:=guiCtrls[idNow].extent.horiz ;
          else
            guiCtrls[idNow].rext.horiz:=guiCtrls[idNow].extent.horiz ;
          end;

          case guiCtrls[idNow].vertSizing of
            heightV: guiCtrls[idNow].rext.vert:=guiCtrls[guiCtrls[idNow].parent].rext.vert;
            bottomV: guiCtrls[idNow].rext.vert:=guiCtrls[idNow].extent.vert ;
            relativeV:begin
                      ratio:=(guiCtrls[guiCtrls[idNow].parent].extent.vert) / (guiCtrls[guiCtrls[idNow].parent].rext.vert);
                      guiCtrls[idNow].rext.vert:= trunc(guiCtrls[idNow].extent.vert / ratio);
                      end;
            centerV: guiCtrls[idNow].rext.vert:=guiCtrls[idNow].extent.vert ;
          else
            guiCtrls[idNow].rext.vert:=guiCtrls[idNow].extent.vert ;
          end;
       end;

   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Panel2.Visible:=False;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  xml:TTreeViewToXML;
begin
  xml:=TTreeViewToXML.Create(TreeView1,GuiCtrls);
  xml.SaveToFile('newgui.xml');
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  xml:TXMLToTreeView;
  fuck:TAGuiCtrls;
  i:integer;
begin
  showmessage('DO NOT PRESS ME!!!!!');
  xml:=TXMLToTreeView.Create;
  fuck:=xml.XMLToTree(TreeView1,'newgui.xml');
  setlength(guiCtrls,length(fuck));
  for i:=1 to length(fuck) do begin
    fuck[i-1]:=TGuiCtrl.create;
    fuck[i-1]:=guiCtrls[i-1];
  end;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  if ResolutionCombo.ItemIndex = 0 then begin
  Panel1.Width:=800; Panel1.Height:=600;
  guiCtrls[0].setExtent('800 600');
  guiCtrls[0].rext.horiz:=800;
  guiCtrls[0].rext.vert:=600;end else
  if ResolutionCombo.ItemIndex = 1 then begin
  Panel1.Width:=1024; Panel1.Height:=768;
  guiCtrls[0].setExtent('1024 768');
  guiCtrls[0].rext.horiz:=1024;
  guiCtrls[0].rext.vert:=768; end else
  if ResolutionCombo.ItemIndex = 2 then begin
  Panel1.Width:=1280; Panel1.Height:=1024;
  guiCtrls[0].setExtent('1280 1024');
  guiCtrls[0].rext.horiz:=1280;
  guiCtrls[0].rext.vert:=1024; end;
  realUpdate;
end;

procedure TForm1.CtrlCoverMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  MPos.Caption:='X:'+inttostr(guiCtrls[selectId].rpos.horiz+X)
              +' Y:'+inttostr(guiCtrls[selectId].rpos.vert+Y);
  mouseX:=X; mouseY:=Y;
end;

procedure TForm1.CtrlCoverMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  MPos.Caption:='X:'+inttostr(guiCtrls[selectId].rpos.horiz+X)
              +' Y:'+inttostr(guiCtrls[selectId].rpos.vert+Y);
end;

procedure TForm1.CtrlCoverMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  MPos.Caption:='X:'+inttostr(guiCtrls[selectId].rpos.horiz+X)
              +' Y:'+inttostr(guiCtrls[selectId].rpos.vert+Y)+#13+
                'X:'+inttostr(X-mouseX)+' Y:'+inttostr(Y-mouseY);
  CtrlCover.Left:=guiCtrls[selectId].rpos.horiz+X-mouseX;
  CtrlCover.Top:=guiCtrls[selectId].rpos.vert+Y-mouseY;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  if (Form1.Width>=944) and (Form1.Height>=639) then begin
  TreeView1.Left:=Form1.Width-208;
  StringGrid1.Left:=Form1.Width-208;
  ApplyChange.Left:=Form1.Width-208;
  ScrollBox1.Width:=Form1.Width-208;
  ScrollBox1.Height:=Form1.Height-105;
  GroupBox1.Width:=Form1.Width-208;
  GroupBox1.Top:=Form1.Height-80;
  end else begin
  Form1.Width:=944;
  Form1.Height:=639;
  end;
end;

procedure TForm1.NextTextClick(Sender: TObject);
begin
  dlgcase:=dlgcase+1;
  case dlgcase of
      1:begin setAskBalloonText('啊,我刚刚用了你的','软件,真的好难用啊!');
        setBalloonText(0,'',''); end;

      2:begin setAskBalloonText('0','');
        setBalloonText(11,'啊？是这样吗？','应该是你不会用吧笨蛋~'); end;

      3:begin setAskBalloonText('你又没告诉我该怎么用','还说我是笨蛋啊喂!');
        setBalloonText(0,'',''); end;

      4:begin setAskBalloonText('0','');
        setBalloonText(10,'好啦好啦，那就','让我来教教你吧。'); end;

      5:begin setAskBalloonText('0','!');
        setBalloonText(12,'首先，需要点击左上按钮来','加载一个gui文件~'); end;

      6:begin setAskBalloonText('0','');
        setBalloonText(10,'当你看到It is done时','一切就都加载好咯'); end;

      7:begin setAskBalloonText('才不是呢！！','什么都没有显示嘛！');
        setBalloonText(0,'',''); end;

      8:begin setAskBalloonText('0','');
        setBalloonText(8,'⑨同学您点击','Draw GUI了吗'); end;

      9:begin setAskBalloonText('0','');
        setBalloonText(8,'只有点击那个按钮','才会开始绘制的哦'); end;

     10:begin setAskBalloonText('那..在右面改完属性','该不会还要点...');
        setBalloonText(8,'Apply Change','按钮'); end;

     11:begin setAskBalloonText('0','');
        setBalloonText(7,'任何操作进行后','都要点的哦'); end;

     12:begin setAskBalloonText('但是点了⑨遍后点Save','退出依然还是老样子');
        setBalloonText(0,'',''); end;

     13:begin setAskBalloonText('0','');
        setBalloonText(10,'看看..果然是笨蛋咯..','点Save会生成新文件的'); end;

     14:begin setAskBalloonText('0','');
        setBalloonText(10,'去程序所在文件夹找找','会找到newgui.gui哦'); end;

     15:begin setAskBalloonText('是...这样吗...','真是麻烦....');
        setBalloonText(0,'',''); end;

     16:begin setAskBalloonText('0','');
        setBalloonText(10,'诶？','你是在学我说画？'); end;

     17:begin showmessage('把鼠标停留在按钮上会有提示出现的哦');
        Panel2.Visible:=false ; end;
  end;
end;

procedure TForm1.VisibleDrawGuiBtnClick(Sender: TObject);
begin
  if ResolutionCombo.ItemIndex = 0 then begin
  Panel1.Width:=800; Panel1.Height:=600;
  guiCtrls[0].setExtent('800 600');  end else
  if ResolutionCombo.ItemIndex = 1 then begin
  Panel1.Width:=1024; Panel1.Height:=768;
  guiCtrls[0].setExtent('1024 768');  end else
  if ResolutionCombo.ItemIndex = 2 then begin
  Panel1.Width:=1280; Panel1.Height:=1024;
  guiCtrls[0].setExtent('1280 1024');  end;
  ClearGUI;
  VisibleDrawGUI(TreeView1.Items.GetFirstNode);
end;

procedure TForm1.DrawGUIBtnClick(Sender: TObject);
begin
  if ResolutionCombo.ItemIndex = 0 then begin
  Panel1.Width:=800; Panel1.Height:=600;
  guiCtrls[0].setExtent('800 600');
  guiCtrls[0].rext.horiz:=800;
  guiCtrls[0].rext.vert:=600;end else
  if ResolutionCombo.ItemIndex = 1 then begin
  Panel1.Width:=1024; Panel1.Height:=768;
  guiCtrls[0].setExtent('1024 768');
  guiCtrls[0].rext.horiz:=1024;
  guiCtrls[0].rext.vert:=768; end else
  if ResolutionCombo.ItemIndex = 2 then begin
  Panel1.Width:=1280; Panel1.Height:=1024;
  guiCtrls[0].setExtent('1280 1024');
  guiCtrls[0].rext.horiz:=1280;
  guiCtrls[0].rext.vert:=1024; end;
  ClearGUI;
  DrawGUI(TreeView1.Items.GetFirstNode);
end;

procedure TForm1.ComboBox2Exit(Sender: TObject);
begin
  with Sender as TComboBox do
  begin
    hide;
    if itemindex >= 0 then
      with StringGrid1 do
        Cells[col, row] := Items[itemindex];
  end;
end;

procedure TForm1.DrawGUI(aItem:TTreeNode);
var
  node:TTreeNode;
  ts:string;
  i,skipThis:integer;
begin
  SetLength(ctrlPic, TreeView1.Items.Count{+1});
  node:=aItem;
  while node<>nil do begin

      i:=getIdFormNodeName(node.text);
      ctrlPic[i]:= TImage.Create(Self);

      skipThis:=0;
      if FileExists(PChar(guiCtrls[i].bitmap)) then
        ts:=guiCtrls[i].bitmap else
      if FileExists(PChar(guiCtrls[i].bitmap+'.png')) then
        ts:=guiCtrls[i].bitmap+'.png' else
      if FileExists(PChar(guiCtrls[i].bitmap+'.jpg')) then
        ts:=guiCtrls[i].bitmap+'.jpg' else
      if FileExists(PChar(guiCtrls[i].bitmap+'_n.png')) then
        ts:=guiCtrls[i].bitmap+'_n.png' else
      if FileExists(PChar(guiCtrls[i].bitmap+'_n.jpg')) then
        ts:=guiCtrls[i].bitmap+'_n.jpg' else
      if (guiCtrls[i].bitmap='Bitmap Path Here') then
        ts:='Bitmap Path Here' else
      if (Checkbox1.Checked) then
        ts:='N/I' else skipThis:=1;

      if (skipThis=0) and (guiCtrls[i].visoverride) then begin//consider visible here... -- Chirsno
      //ctrlPic属性定义
      //ctrlPic[i]:= TImage.Create(Self);
      ctrlPic[i].Parent:=Panel1;
      if (ts='Bitmap Path Here') then ctrlPic[i].Picture:=Image3.Picture else
      if (ts='N/I') then ctrlPic[i].Picture:=Image5.Picture else
        ctrlPic[i].Picture.LoadFromFile(PChar(ts));
      ctrlPic[i].stretch:=true;
      ctrlPic[i].Left:=guiCtrls[i].rpos.horiz;
      ctrlPic[i].Top:=guiCtrls[i].rpos.vert;
      ctrlPic[i].width:=guiCtrls[i].rext.horiz; //extent to rext
      ctrlPic[i].height:=guiCtrls[i].rext.vert; //extent to rext

      end else skipThis:=0;

      if node.HasChildren then
        DrawGUI(node.getFirstChild);
      node:=node.getNextSibling;

    //end;
  end;

end;

procedure TForm1.VisibleDrawGUI(aItem:TTreeNode);
var
  node:TTreeNode;
  ts:string;
  i,skipThis:integer;
begin
  SetLength(ctrlPic, TreeView1.Items.Count{+1});
  node:=aItem;
  while node<>nil do begin

      i:=getIdFormNodeName(node.text);
      ctrlPic[i]:= TImage.Create(Self);

      skipThis:=0;
      if FileExists(PChar(guiCtrls[i].bitmap)) then
        ts:=guiCtrls[i].bitmap else
      if FileExists(PChar(guiCtrls[i].bitmap+'.png')) then
        ts:=guiCtrls[i].bitmap+'.png' else
      if FileExists(PChar(guiCtrls[i].bitmap+'.jpg')) then
        ts:=guiCtrls[i].bitmap+'.jpg' else
      if FileExists(PChar(guiCtrls[i].bitmap+'_n.png')) then
        ts:=guiCtrls[i].bitmap+'_n.png' else
      if FileExists(PChar(guiCtrls[i].bitmap+'_n.jpg')) then
        ts:=guiCtrls[i].bitmap+'_n.jpg' else
      if (guiCtrls[i].bitmap='Bitmap Path Here') then
        ts:='Bitmap Path Here' else
      if (Checkbox1.Checked) then
        ts:='N/I' else skipThis:=1;

      if (skipThis=0) then begin
      //ctrlPic属性定义
      //ctrlPic[i]:= TImage.Create(Self);
      ctrlPic[i].Parent:=Panel1;
      if (ts='Bitmap Path Here') then ctrlPic[i].Picture:=Image3.Picture else
      if (ts='N/I') then ctrlPic[i].Picture:=Image5.Picture else
        ctrlPic[i].Picture.LoadFromFile(PChar(ts));
      ctrlPic[i].stretch:=true;
      ctrlPic[i].Left:=guiCtrls[i].rpos.horiz;
      ctrlPic[i].Top:=guiCtrls[i].rpos.vert;
      ctrlPic[i].width:=(guiCtrls[i].rext.horiz);//extent to rext
      ctrlPic[i].height:=(guiCtrls[i].rext.vert);
      end else skipThis:=0;

      if node.HasChildren then
        VisibleDrawGUI(node.getFirstChild);
      node:=node.getNextSibling;

    //end;
  end;

end;

procedure TForm1.ClearGUI;
var
  i,j:integer;
begin
  if Panel1.ControlCount=1 then exit;

  j:=TreeView1.Items.Count-1;//Panel1.ControlCount;
  for i:=1 to j do
       ctrlPic[i].free;

  CtrlCover.Left:=732;
  CtrlCover.Top:=528;
  CtrlCover.visible:=false;
end;

procedure TForm1.SaveBtnClick(Sender: TObject);
begin
  assignfile(ttext, 'newgui.gui');
  rewrite(ttext);
  writeln(ttext,'//--- OBJECT WRITE BEGIN ---');
  //do sth
  //outputAsGuiFile('',TreeView1.Items.GetFirstNode);
  outputAsGuiFile('',TreeView1.Items.GetFirstNode.Items[0]);
  //------
  writeln(ttext,'//--- OBJECT WRITE END ---');
  closefile(ttext);
  showmessage('done~ see newGui.gui in the folder.');
end;

procedure TForm1.StringGrid1SelectCell(Sender: TObject; aCol, aRow: Integer;
  var CanSelect: Boolean);
var
  R: TRect;
  org: TPoint;
begin
with Sender as TStringGrid do begin
//-----------------------------------------
  //if (ACol = 1) and (ARow >= FixedRows) then 在第一列显示一个ComboBox
  if (ACol = 1) and (ARow = 5) then
  begin
    //perform(WM_CANCELMODE, 0, 0);
    R := CellRect(ACol, ARow);
    org := Self.ScreenToClient(ClientToScreen(R.topleft));
    with ComboBox1 do
    begin
      setbounds(org.X, org.Y, R.right - R.left, height);
      itemindex := Items.IndexOf(Cells[ACol, ARow]);
      Show;
      BringTofront;
      SetFocus;
      DroppedDown := true;
    end;
  end;
  if (ACol = 1) and (ARow = 6) then
  begin
    //perform(WM_CANCELMODE, 0, 0);
    R := CellRect(ACol, ARow);
    org := Self.ScreenToClient(ClientToScreen(R.topleft));
    with ComboBox2 do
    begin
      setbounds(org.X, org.Y, R.right - R.left, height);
      itemindex := Items.IndexOf(Cells[ACol, ARow]);
      Show;
      BringTofront;
      SetFocus;
      DroppedDown := true;
    end;
  end;
//-------------------------------------------------
  end;
end;

procedure TForm1.NewGUICtrlBtnClick(Sender: TObject);
var
  i:integer;
begin
  if Treeview1.Selected = nil then Exit;
  i:=TreeView1.Items.Count+1;
  SetLength(ctrlPic, i);
  SetLength(guiCtrls, i);
  i:=i-1;
  TreeView1.Items.AddChild(TreeView1.Selected, inttostr(i)+':GUI TreeView');
  ctrlPic[i]:= TImage.Create(Self);
  guiCtrls[i]:=TGuiCtrl.create;

  ctrlPic[i].Parent:=Panel1;
  ctrlPic[i].Picture:=Image3.Picture;
  ctrlPic[i].stretch:=true;
  ctrlPic[i].Left:=0;
  ctrlPic[i].Top:=0;
  ctrlPic[i].width:=199;
  ctrlPic[i].height:=199;

  guiCtrls[i].setParent(getIdFormNodeName(TreeView1.Selected.Text));
  guiCtrls[i].setProfile('GuiDefaultProfile');
  guiCtrls[i].setFunctionName('GuiBitmapCtrl');
  guiCtrls[i].setPosition('0 0');
  guiCtrls[i].setExtent('199 199');
  guiCtrls[i].setVisible('1');
  guiCtrls[i].setBitmap('Bitmap Path Here');

end;

procedure TForm1.TreeView1Click(Sender: TObject);
var
   ts: string;
begin
if Treeview1.Selected = nil then Exit;
//节点的等级level根节点为0,根节点的子节点为1..
//序号index同等级下的的节点按从上到下数第一个为0,第二个为1..
if(treeview1.Selected.Level = 0)and(treeview1.Selected.Index = 0) then
begin
   CtrlCover.visible:=false;
end
else
if not ((treeview1.Selected.Level = 0)and(treeview1.Selected.Index=0)) then
begin
   //stringgrid1.cells[stringgrid1.col,stringgrid1.row]:='想要输入的值'
   ts:=TreeView1.selected.Text;
   ts:=copy(ts,1,pos(':',ts)-1);

   selectId:=strtoint(ts);

   stringgrid1.cells[1,1]:=guiCtrls[strtoint(ts)].functionName;
   stringgrid1.cells[1,2]:=guiCtrls[strtoint(ts)].name;
   stringgrid1.cells[1,3]:=ts;
   stringgrid1.cells[1,4]:=guiCtrls[strtoint(ts)].profile;
   stringgrid1.cells[1,5]:=guiCtrls[strtoint(ts)].viewHorizSizing;
   stringgrid1.cells[1,6]:=guiCtrls[strtoint(ts)].viewVertSizing;
   stringgrid1.cells[1,7]:=guiCtrls[strtoint(ts)].viewPosition;
   stringgrid1.cells[1,8]:=guiCtrls[strtoint(ts)].viewExtent;
   stringgrid1.cells[1,10]:=inttostr(ord(guiCtrls[strtoint(ts)].visible));
   stringgrid1.cells[1,12]:=guiCtrls[strtoint(ts)].bitmap;
   stringgrid1.cells[1,14]:=inttostr(guiCtrls[strtoint(ts)].codeLine);

   CtrlCover.visible:=true;
   CtrlCover.Left:=guiCtrls[strtoint(ts)].rpos.horiz;
   CtrlCover.Top:=guiCtrls[strtoint(ts)].rpos.vert;
   CtrlCover.Width:=guiCtrls[strtoint(ts)].rext.horiz;//extent to rext
   CtrlCover.Height:=guiCtrls[strtoint(ts)].rext.vert;//
   CtrlCover.BringToFront;

   if (strtoint(ts)<>-1) then
      MPos.caption:='GuiCtrlRPos ' + guiCtrls[strtoint(ts)].viewRPos
                           + ' RExtent ' + guiCtrls[strtoint(ts)].viewRExt +#13#10+
                    'ParentRPos ' + guiCtrls[guiCtrls[strtoint(ts)].parent].viewRPos
                           + ' RExtent ' + guiCtrls[guiCtrls[strtoint(ts)].parent].viewRExt
   else
      MPos.caption:='GuiCtrlPos ' + guiCtrls[strtoint(ts)].viewRPos
                           + 'extent ' + guiCtrls[strtoint(ts)].viewExtent;

end;
end;

function TForm1.getIdFormNodeName(ts: string):Integer;
begin
  ts:=copy(ts,1,pos(':',ts)-1);
  result:=strtoint(ts);
end;

procedure TForm1.outputAsGuiFile(s:string;aItem:TTreeNode);
var                    //TODO let ^this var to make a indent
  node:TTreeNode;
  str:string;
  id:integer;
begin
  node:=aItem;
  while node<>nil do begin
    //we should output a block without '};' item
       id:=getIdFormNodeName(node.Text);
    //if guiCtrls[id].name='yooooooooo' then node:=node.getNextSibling else
    //begin
       str:='new '+guiCtrls[id].functionName+'('+guiCtrls[id].name+') {';
       writeln(ttext, str);//form1.ListBox1.Items.Add(str);
       str:='   profile = "'+guiCtrls[id].profile+'";';
       writeln(ttext, str);
       str:='   horizSizing = "'+guiCtrls[id].viewHorizSizing+'";';
       writeln(ttext, str);
       str:='   vertSizing = "'+guiCtrls[id].viewVertSizing+'";';
       writeln(ttext, str);
       str:='   position = "'+guiCtrls[id].viewPosition+'";';
       writeln(ttext, str);
       str:='   extent = "'+guiCtrls[id].viewExtent+'";';
       writeln(ttext, str);
       str:='   bitmap = "'+guiCtrls[id].bitmap+'";';
       writeln(ttext, str);
       str:='   visiable = "'+inttostr(ord(guiCtrls[id].visible))+'";';
       writeln(ttext, str);


      if node.HasChildren then
      begin
        outputAsGuiFile(' ',node.getFirstChild);
        writeln(ttext,'};');
      end else writeln(ttext,'};'); //i had done sth stupid..
      node:=node.getNextSibling;

    //end;
  end;
end;

procedure TForm1.setBalloonText(textNum:integer;TextLO,TextLT:string);
begin
if (textNum>=11) and (textNum<=12) then
begin
  balloonLeft.Left:=496; //W=80
  //balloonLeft.Top:=336;  //H=100
  balloonMidd.Left:=576; //W=20
  balloonMidd.Width:=40;  //H=100
  balloonRight.Left:=616; //W=80
  //balloonRight.Top:=336;  //H=100
  GuideText.Left:=528;
  //GuideText.Top:=376;
  GuideText.Width:=128;
  GuideText.Height:=40;
  GuideText.caption:=TextLO+#13#10+TextLT;
end;
if (textNum>=8) and (textNum<=10) then
begin
  balloonLeft.Left:=520; //W=80
  //balloonLeft.Top:=336;  //H=100
  balloonMidd.Left:=600; //W=20
  //balloonMidd.Top:=336;  //H=100
  balloonRight.Left:=616; //W=80
  //balloonRight.Top:=336;  //H=100
  GuideText.Left:=552;
  //GuideText.Top:=376;
  GuideText.Width:=128;
  GuideText.Height:=40;
  GuideText.caption:=TextLO+#13#10+TextLT;
end;
if (textNum<=7) and (textNum>=1) then
begin
  balloonLeft.Left:=544; //W=80
  //balloonLeft.Top:=336;  //H=100
  balloonMidd.Left:=600; //W=20
  //balloonMidd.Top:=336;  //H=100
  balloonRight.Left:=616; //W=80
  //balloonRight.Top:=336;  //H=100
  GuideText.Left:=580;
  //GuideText.Top:=376;
  GuideText.Width:=128;
  GuideText.Height:=40;
  GuideText.caption:=TextLO+#13#10+TextLT;
end;
if (textNum=0) then
begin
  balloonLeft.Left:=944; //W=80
  //balloonLeft.Top:=336;  //H=100
  balloonMidd.Left:=944; //W=20
  //balloonMidd.Top:=336;  //H=100
  balloonRight.Left:=944; //W=80
  //balloonRight.Top:=336;  //H=100
  GuideText.Left:=944;
  //GuideText.Top:=376;
  GuideText.Width:=128;
  GuideText.Height:=40;
  GuideText.caption:=TextLO+#13#10+TextLT;
end;
end;

procedure TForm1.setAskBalloonText(TextLO,TextLT:string);
begin
  AskBalloon.Left:=280; //W=80
  //balloonLeft.Top:=336;  //H=100
  GuideText.Left:=944;
  //GuideText.Top:=376;
  AskBalloonText.Top:=376;
  AskBalloonText.Left:=304;
  AskBalloonText.caption:=TextLO+#13#10+TextLT; //#13 for win and #10 for linux
  if TextLO='0' then
  begin
    AskBalloon.Left:=944;
    AskBalloonText.Top:=944;
  end;
end;

end.

